

#include "delay.h"
#include "printf.h"
#include <stdbool.h>
#include <stdio.h>
#include <stm32f10x.h>

void LED_init() {

    GPIO_InitTypeDef def;
    def.GPIO_Mode = GPIO_Mode_Out_PP;
    def.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
    def.GPIO_Speed = GPIO_Speed_50MHz;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    // 要开启 复用 RCC_APB2Periph_AFIO 才能禁用 PB3,PB4的先被占用的引脚功能
    //  JTDO/TRACESWO PB3
    //  JNTRST PB4
    //  PB3,PB4 程序还没开始就已经被占用了，需要设置恢复它的IO功能！！！
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
    GPIO_Init(GPIOB, &def);
    // B3 必须为 0 ，也就是 - ，上面虽然是一个 -，但是它狗日的是一个接地，
    // 否则无法亮灯。“-”代表接地！！！
    GPIO_Write(GPIOB, ~0x78);
}

void LED_R_on_or_off() {
    static bool on = true;

    if (on) {
        GPIO_WriteBit(GPIOB, GPIO_Pin_4, Bit_SET);
    } else {
        GPIO_WriteBit(GPIOB, GPIO_Pin_4, Bit_RESET);
    }
    on = !on;
}
void LED_G_on_or_off() {
    static bool on = true;

    if (on) {
        GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET);
    } else {
        GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_RESET);
    }
    on = !on;
}
void LED_B_on_or_off() {
    static bool on = true;

    if (on) {
        GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);
    } else {
        GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_RESET);
    }
    on = !on;
}

void TIM2_init() {
    NVIC_InitTypeDef NVIC_initial;
    TIM_TimeBaseInitTypeDef TIM_initial;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // config
    TIM_initial.TIM_Period = 10000 - 1;
    TIM_initial.TIM_Prescaler = 7200 - 1;
    TIM_initial.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_initial);

    // NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);

    NVIC_initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_initial.NVIC_IRQChannelCmd = ENABLE;
    NVIC_initial.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_Init(&NVIC_initial);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM2, ENABLE);
}

void TIM2_IRQHandler() {
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {
        printf("Timer 2 runing\r\n");
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        LED_R_on_or_off();
    }
}

void TIM3_init() {
    NVIC_InitTypeDef NVIC_initial;
    TIM_TimeBaseInitTypeDef TIM_initial;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // config
    TIM_initial.TIM_Period = 5000 - 1;
    TIM_initial.TIM_Prescaler = 7200 - 1;
    TIM_initial.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_initial);

    // NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);

    NVIC_initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_initial.NVIC_IRQChannelCmd = ENABLE;
    NVIC_initial.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_Init(&NVIC_initial);

    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM3, ENABLE);
}

void TIM3_IRQHandler() {
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) {
        printf("Timer 3 runing\r\n");
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
        LED_G_on_or_off();
    }
}
void TIM4_init() {
    NVIC_InitTypeDef NVIC_initial;
    TIM_TimeBaseInitTypeDef TIM_initial;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    // config
    TIM_initial.TIM_Period = 1000 - 1;
    TIM_initial.TIM_Prescaler = 7200 - 1;
    TIM_initial.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_initial);

    // NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);

    NVIC_initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_initial.NVIC_IRQChannelSubPriority = 2;
    NVIC_initial.NVIC_IRQChannelCmd = ENABLE;
    NVIC_initial.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_Init(&NVIC_initial);

    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM4, ENABLE);
}

void TIM4_IRQHandler() {
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) {
        printf("Timer 4 runing\r\n");
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
        LED_B_on_or_off();
    }
}

int main() {

    printf_init(9600);
    delay_init();
    TIM2_init();
    TIM3_init();
    TIM4_init();
    LED_init();

    while (true) {

        // printf("__initial_sp = %#X\r\n", __initial_sp);
        // printf("__heap_base = %#X\r\n", __heap_base);
        // printf("__heap_limit = %#X\r\n", __heap_limit);
        printf("main running\r\n");
        // printf("PriorityGroup is %d\r\n", NVIC_GetPriorityGrouping());
        printf("GPIOB:%#X\r\n", GPIO_ReadInputData(GPIOB));
        delay_s(3);
    }

    return 0;
}
